﻿// Project: Salient
// http://salient.codeplex.com
// 
// Copyright 2010, Sky Sanders <sky at skysanders.net>
// Dual licensed under the MIT or GPL Version 2 licenses.
// http://salient.codeplex.com/license
// 
// Date: April 16 2010 

#region

using System;

#endregion

namespace Salient.Web
{
    ///<summary>
    ///</summary>
    public static class Conversions
    {
        ///<summary>
        ///</summary>
        ///<param name="obj"></param>
        ///<typeparam name="T"></typeparam>
        ///<returns></returns>
        public static T To<T>(this IConvertible obj)
        {
            Type t = typeof (T);

            if (t.IsGenericType
                && (t.GetGenericTypeDefinition() == typeof (Nullable<>)))
            {
                if (obj == null)
                {
                    return (T) (object) null;
                }
                return (T) Convert.ChangeType(obj, Nullable.GetUnderlyingType(t));
            }
            return (T) Convert.ChangeType(obj, t);
        }

        ///<summary>
        ///</summary>
        ///<param name="obj"></param>
        ///<typeparam name="T"></typeparam>
        ///<returns></returns>
        public static T ToOrDefault<T>(this IConvertible obj)
        {
            try
            {
                return To<T>(obj);
            }
            catch
            {
                return default(T);
            }
        }

        ///<summary>
        ///</summary>
        ///<param name="obj"></param>
        ///<param name="newObj"></param>
        ///<typeparam name="T"></typeparam>
        ///<returns></returns>
        public static bool ToOrDefault<T>
            (this IConvertible obj,
             out T newObj)
        {
            try
            {
                newObj = To<T>(obj);
                return true;
            }
            catch
            {
                newObj = default(T);
                return false;
            }
        }

        ///<summary>
        ///</summary>
        ///<param name="obj"></param>
        ///<param name="other"></param>
        ///<typeparam name="T"></typeparam>
        ///<returns></returns>
        public static T ToOrOther<T>(this IConvertible obj,T other)
        {
            try
            {
                return To<T>(obj);
            }
            catch
            {
                return other;
            }
        }

        ///<summary>
        ///</summary>
        ///<param name="obj"></param>
        ///<param name="newObj"></param>
        ///<param name="other"></param>
        ///<typeparam name="T"></typeparam>
        ///<returns></returns>
        public static bool ToOrOther<T>(this IConvertible obj,out T newObj,T other)
        {
            try
            {
                newObj = To<T>(obj);
                return true;
            }
            catch
            {
                newObj = other;
                return false;
            }
        }

        ///<summary>
        ///</summary>
        ///<param name="obj"></param>
        ///<typeparam name="T"></typeparam>
        ///<returns></returns>
        public static T ToOrNull<T>(this IConvertible obj) where T : class
        {
            try
            {
                return To<T>(obj);
            }
            catch
            {
                return null;
            }
        }

        ///<summary>
        ///</summary>
        ///<param name="obj"></param>
        ///<param name="newObj"></param>
        ///<typeparam name="T"></typeparam>
        ///<returns></returns>
        public static bool ToOrNull<T>(this IConvertible obj,out T newObj) where T : class
        {
            try
            {
                newObj = To<T>(obj);
                return true;
            }
            catch
            {
                newObj = null;
                return false;
            }
        }
    }
}